package com.slashvision.im.ui

import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.compose.foundation.*
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.rememberTransformableState
import androidx.compose.foundation.gestures.transformable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.*
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.input.pointer.consumeAllChanges
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.*
import androidx.constraintlayout.compose.ConstraintLayout
import coil.ImageLoader
import coil.compose.LocalImageLoader
import coil.compose.rememberImagePainter
import coil.imageLoader
import coil.request.ImageRequest
import com.google.accompanist.imageloading.LoadPainterDefaults
import com.google.accompanist.imageloading.ShouldRefetchOnSizeChange
import com.google.accompanist.insets.ProvideWindowInsets
import com.google.accompanist.insets.statusBarsHeight
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.slashvision.im.ContextUtil
import com.slashvision.im.R
import com.slashvision.im.SLog
import com.slashvision.im.ui.theme.IMTheme
import java.io.File

/**
 * author : lizhenxin
 *  date  : 2021/10/26
 *  desc  :
 */
/**
 * @desc:
 * @author: LiZhenxin
 * @create:
 * update
 **/


@Composable
fun ComposeToolbar(
    title: String,
    titleSize: TextUnit = 16.sp,
    @ColorRes titleColor: Int = R.color.black_2,
    layoutModifier: Modifier = Modifier,
    titleModifier: Modifier = Modifier.fillMaxWidth(),
    isBackIconVisible: Boolean = false,
    onBackClick: () -> Unit = {},
    rightLayout: @Composable () -> Unit = {},
) {
    ConstraintLayout(
        modifier = layoutModifier
            .height(48.dp)
            .fillMaxWidth()
            .background(colorResource(id = R.color.global_board))
    ) {
        val rTitle = createRef()
        val rBack = createRef()
        val rRight = createRef()
        val rSpacer = createRef()

        Text(
            title,
            fontSize = titleSize,
            color = colorResource(id = titleColor),
            modifier = titleModifier
                .constrainAs(rTitle) {
                    centerHorizontallyTo(parent)
                    centerVerticallyTo(rBack)
                }
                .wrapContentWidth(),
        )
        if (isBackIconVisible) {
            Button(
                onClick = { onBackClick() },
                enabled = onBackClick != {},
                colors = ButtonDefaults.buttonColors(backgroundColor = colorResource(id = R.color.global_board)),
                modifier = Modifier
                    .constrainAs(rBack) {
                        start.linkTo(parent.start)
                        bottom.linkTo(parent.bottom)
                    }
                    .size(48.dp),
                elevation = null
            ) {
                Icon(
                    painter = painterResource(id = R.drawable.ic_back),
                    contentDescription = "back"
                )
            }

        }
        Surface(
            content = rightLayout,
            modifier = Modifier
                .constrainAs(rRight) {
                    end.linkTo(parent.end, 16.dp)
                    centerVerticallyTo(rBack)
                }
                .wrapContentWidth()
        )
        Spacer(
            modifier = Modifier
                .constrainAs(rSpacer) {
                    bottom.linkTo(parent.bottom)
                    centerHorizontallyTo(parent)
                }
                .fillMaxWidth()
                .height(1.dp)
                .background(colorResource(id = R.color.toolbar_spacer))
        )
    }
}


@Composable
fun UScreen(
    modifier: Modifier = Modifier.fillMaxSize(),
    statusBarColor: Color = colorResource(id = R.color.global_board),
    isDark: Boolean = isSystemInDarkTheme(),
    insertStatusPadding: Boolean = true,
    content: @Composable () -> Unit
) {
    Surface(
        modifier = modifier
            .fillMaxSize()
            .background(colorResource(id = R.color.global_board))
    ) {
        IMTheme(darkTheme = isDark) {
            ProvideWindowInsets {
                rememberSystemUiController().setStatusBarColor(statusBarColor, darkIcons = !isDark)
                Column {
                    if (insertStatusPadding) {
                        Spacer(
                            modifier = Modifier
                                .fillMaxWidth()
                                .statusBarsHeight()
                                .background(colorResource(id = R.color.global_board))

                        )
                    }
                    content()
                }
            }
        }
    }
}

@Composable
fun UText(
    text: String,
    size: TextUnit = 12.sp,
    weight: FontWeight = FontWeight.Normal,
    color: Color = colorResource(id = R.color.black_2),
    align: TextAlign = TextAlign.Start,
    backgroundColor: Color = colorResource(id = R.color.transparent),
    shape: Shape = RectangleShape,
    borderWidth: Dp = 0.dp,
    borderColor: Color = colorResource(id = R.color.color_97),
    borderShape: Shape = RoundedCornerShape(50),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    maxLines: Int = 1,
    modifier: Modifier = Modifier
) {
    var m = modifier

        .background(color = backgroundColor, shape = shape)

    if (borderWidth.value > 0) {
        m = m.border(borderWidth, borderColor, borderShape)
    }
    m = m.padding(contentPadding)
    Text(
        text = text,
        fontSize = size,
        color = color,
        textAlign = align,
        maxLines = maxLines,
        fontWeight = weight,
        modifier = m
    )
}


@Composable
fun RoundedCornerButton(
    text: String,
    textSize: TextUnit = 12.sp,
    textColor: Color = colorResource(id = R.color.black_2),
    bacColor: Color = colorResource(id = R.color.dialog_color),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    maxLines: Int = 1,
    modifier: Modifier = Modifier,
    onClick: (String) -> Unit = {}
) = UText(
    text = text,
    size = textSize,
    color = textColor,
    backgroundColor = bacColor,
    shape = RoundedCornerShape(50),
    maxLines = maxLines,
    contentPadding = contentPadding,
    align = TextAlign.Center,
    modifier = modifier.clickable { onClick(text) }
)

@Composable
fun ColorToggleButton(
    text: String,
    toggleState: Boolean,
    onColor: Color = colorResource(id = R.color.main_blue),
    offColor: Color = colorResource(id = R.color.unconfirm),
    onTextColor: Color = colorResource(id = R.color.white),
    offTextColor: Color = colorResource(id = R.color.text_unconfirm),
    textSize: TextUnit = 14.sp,
    textPadding: PaddingValues = PaddingValues(horizontal = 14.dp, vertical = 4.dp),
    shape: Shape = RoundedCornerShape(50),
    modifier: Modifier = Modifier
) = UText(
    text = text,
    color = if (toggleState) onTextColor else offTextColor,
    size = textSize,
    backgroundColor = if (toggleState) onColor else offColor,
    shape = shape,
    contentPadding = textPadding,
    modifier = modifier
)


@Composable
fun Spinner(
    text: String,
    items: List<String>,
    onClick: (Int) -> Unit
) {
    val titleState = remember {
        mutableStateOf(text)
    }
    val expendState = remember {
        mutableStateOf(false)
    }
    Column {
        Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clickable {
            expendState.value = !expendState.value
        }) {
            Spacer(modifier = Modifier.size(6.dp))
            UText(
                text = titleState.value,
                size = 14.sp,
                contentPadding = PaddingValues(horizontal = 13.dp, vertical = 10.dp)
            )
            Image(
                painter = painterResource(id = if (expendState.value) R.drawable.ic_up else R.drawable.ic_down),
                contentDescription = null,
                modifier = Modifier.size(10.dp)
            )
        }
        if (expendState.value) {
            Column {
                items.forEachIndexed { index, it ->
                    UText(
                        text = it,
                        contentPadding = PaddingValues(horizontal = 13.dp, vertical = 10.dp),
                        modifier = Modifier.clickable {
                            onClick(index)
                            titleState.value = it
                            expendState.value = !expendState.value
                        }
                    )
                }
            }
        }
    }
}


/**
 * @param isLocal   是否是本地图片
 */
@ExperimentalComposeUiApi
@Composable
fun UImage(
    request: String,
    isLocal: Boolean = false,
    contentScale: ContentScale = ContentScale.FillWidth,
    corner: Dp = 0.dp,
    maxSize: Boolean = true,
    width: Dp = 0.dp,
    height: Dp = 0.dp,
    shape: Shape = RoundedCornerShape(corner),
    canDrag: Boolean = false,
    modifier: Modifier = Modifier,
) {
    if (canDrag) {
        BaseImage(
            painter = myCoilPainter(request = if (isLocal) File(request) else request),
            contentScale = contentScale,
            modifier = modifier.clip(shape)
                .apply {
                    if (maxSize) {
                        this.fillMaxSize()
                    }
                    if (width != 0.dp) {
                        this.width(width)
                    }
                    if (height != 0.dp) {
                        this.height(height)
                    }
                },
            canDrag = canDrag
        )
    } else {
        Image(painter = myCoilPainter(request = if (isLocal) File(request) else request),
            contentDescription = null,
            contentScale = contentScale,
            modifier = modifier.clip(shape)
                .apply {
                    if (maxSize) {
                        this.fillMaxSize()
                    }
                    if (width != 0.dp) {
                        this.width(width)
                    }
                    if (height != 0.dp) {
                        this.height(height)
                    }
                })
    }
}

@ExperimentalComposeUiApi
@Composable
fun BaseImage(
    painter: Painter,
    contentDescription: String? = null,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null,
    canDrag: Boolean = true
) {

    var scale = remember { mutableStateOf(1f) }
    var rotation = remember { mutableStateOf(0f) }
    var offset = remember { mutableStateOf(Offset.Zero) }
    val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
        scale.value *= zoomChange
        rotation.value += rotationChange
        offset.value += offsetChange
    }

    Image(
        painter = painter, contentDescription = contentDescription,
        alignment = alignment,
        contentScale = contentScale,
        alpha = alpha,
        colorFilter = colorFilter,
        modifier = modifier
            .pointerInput(Unit) {
                if (canDrag) {
                    this.detectDragGestures { change, dragAmount ->
                        change.consumeAllChanges()
                        SLog.d("BaseImage", "${dragAmount.x}    ${dragAmount.y}")
                        offset.value += dragAmount
                    }
                }
                /*this.detectTapGestures(onDoubleTap = {
                    scale.value = 1f
                    rotation.value = 0f
                    offset.value = Offset.Zero
                    SLog.d("BaseImage", "---double tap---")
                })*/
            }
            .graphicsLayer(
                scaleX = scale.value,
                scaleY = scale.value,
//                rotationZ = rotation.value,
                translationX = if (canDrag) offset.value.x else 0f,
                translationY = if (canDrag) offset.value.y else 0f
            )
            .transformable(state = state)

    )
}

@ExperimentalComposeUiApi
@Composable
fun UImage(
    @DrawableRes drawableId: Int,
    contentScale: ContentScale = ContentScale.FillWidth,
    corner: Dp = 0.dp,
    maxSize: Boolean = true,
    width: Dp = 0.dp,
    height: Dp = 0.dp,
    shape: Shape = RoundedCornerShape(corner),
    canDrag: Boolean = false,
    modifier: Modifier = Modifier,
    onClick: (Any) -> Unit = {},
) {
    modifier
        .clip(shape)
        .clickable { onClick(drawableId) }
    if (maxSize) {
        modifier.fillMaxSize()
    }
    if (width != 0.dp) {
        modifier.width(width)
    }
    if (height != 0.dp) {
        modifier.height(height)
    }

    BaseImage(
        painter = painterResource(id = drawableId),
        contentScale = contentScale,
        modifier = modifier,
        canDrag = canDrag
    )
}

@Composable
fun myCoilPainter(
    request: Any?,
    imageLoader: ImageLoader = LocalImageLoader.current,
    shouldRefetchOnSizeChange: ShouldRefetchOnSizeChange? = null,
    requestBuilder: (ImageRequest.Builder.(size: IntSize) -> ImageRequest.Builder)? = { this },
    fadeIn: Boolean = false,
    fadeInDurationMs: Int = LoadPainterDefaults.FadeInTransitionDuration,
    @DrawableRes previewPlaceholder: Int = 0,
) = rememberImagePainter(
    data = request,
    imageLoader = ContextUtil.getContext().imageLoader,
    /*builder = {
        ImageRequest.Builder(ContextUtil.getContext()).transformations(RoundedCornersTransformation(15f))
    }*/
)
